// ===============================================
// app_utils
//
// Create by Will on 2020/10/5 3:53 PM
// Copyright Will.All rights reserved.
// ===============================================

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'package:dio/dio.dart' as dio;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:universal_html/html.dart' as html;

import '../const/app_policies.dart';
import '../core/logger.dart';
import '../core/toast.dart';
import 'encrypt_utils.dart';

class AppUtils {
  AppUtils._internal();

  static final HttpClient _sharedHttpClient = HttpClient()
    ..autoUncompress = false;

  static HttpClient get _httpClient {
    var client = _sharedHttpClient;
    assert(() {
      if (debugNetworkImageHttpClientProvider != null) {
        client = debugNetworkImageHttpClientProvider!();
      }
      return true;
    }());
    return client;
  }

  //获取网络图 之后 存进内存中 保存的是data
  static Future<Map<String, dynamic>?> getImage({
    required String url,
    required bool useEncrypt,
    String? contentType = dio.Headers.jsonContentType,
    bool pushCache = true,
  }) async {
    if (url.contains('http')) {
      if (kIsWeb) {
        final header = await EncryptUtils.addCryptKey();

        final headers = <String, String>{};
        if (useEncrypt) {
          //设置请求头
          for (final apiHeader in header.entries) {
            headers[apiHeader.key] = apiHeader.value.toString();
          }
        }

        final xhr = await html.HttpRequest.request(
          url,
          //设置请求头
          requestHeaders: headers,
          responseType: 'arraybuffer',
        ).onError((error, stackTrace) {
          CoreKitLogger().e('getImage error', error, stackTrace);
          toastError(error);
          throw Exception('html.HttpRequest is an error  $error');
        });

        if (xhr.response != null) {
          final resp = <String, dynamic>{};
          final bb = xhr.response as ByteBuffer;
          // return base64Encode(bb.asUint8List());

          await AppPolicies.imageCacheBox?.put(url, bb.asUint8List());
          resp['base64Encode'] = base64Encode(bb.asUint8List());

          final responseHeaders = xhr.response.headers;
          if (responseHeaders['key'] != null) {
            resp['key'] = responseHeaders['key'].toString();
          }

          return resp;
        } else {
          return null;
        }
      } else {
        final resolved = Uri.base.resolve(url);

        final request = await _httpClient.getUrl(resolved);

        if (useEncrypt) {
          final header = await EncryptUtils.addCryptKey();
          //设置请求头
          for (final apiHeader in header.entries) {
            request.headers.set(apiHeader.key, apiHeader.value.toString());
          }
        }

        final response = await request.close();

        if (response.statusCode != HttpStatus.ok) {
          await response.drain<List<int>>(<int>[]);
          throw NetworkImageLoadException(
              statusCode: response.statusCode, uri: resolved);
        }

        final resp = <String, dynamic>{};

        try {
          if (useEncrypt) {
            final responseBody = await response.transform(utf8.decoder).join();

            if (responseBody.isEmpty) {
              throw Exception('CoreNetworkImage is an empty file: $resolved');
            }

            resp['base64Encode'] =
                responseBody.replaceAll(RegExp(r'[\s"\\]'), '');
            final responseHeaders = response.headers;
            if (responseHeaders['key'] != null) {
              final key = responseHeaders['key']!;
              resp['key'] = key[0];
            }

            if (pushCache) {
              //把请求回来的加密数据缓存起来
              await AppPolicies.imageCacheBox!.put(url, resp['base64Encode']);
              if (resp['key'] != null) {
                await AppPolicies.imageCacheBox!.put('$url==key', resp['key']);
              }
            }
          } else {
            final bytes = await consolidateHttpClientResponseBytes(
              response,
            );

            if (bytes.lengthInBytes == 0) {
              throw Exception('CoreNetworkImage is an empty file: $resolved');
            }

            final base64Encode = String.fromCharCodes(bytes);
            resp['base64Encode'] = base64Encode;

            if (pushCache) {
              //把请求回来的加密数据缓存起来
              await AppPolicies.imageCacheBox!.put(url, base64Encode);
            }
          }

          return resp;
        } catch (e, s) {
          CoreKitLogger().e('getImage error by device ', e, s);
          return null;
        }
      }
    } else {
      return null;
    }
  }

  //从缓存获取图片
  static Image getImageForData({
    required Uint8List data,
    double? width,
    double? height,
    BoxFit? fit,
    Widget? errorCover,
  }) {
    return Image.memory(
      data,
      width: width ?? double.infinity,
      height: height ?? double.infinity,
      fit: fit ?? BoxFit.cover,
      gaplessPlayback: true,
      errorBuilder: (context, error, v) {
        // return errorCover ?? AssetImage("assets/images/bg_def.jpg");
        CoreKitLogger().e('Image.memory', error, v);
        return errorCover ?? Container();
      },
      frameBuilder: (context, child, frame, wasSynchronouslyLoaded) {
        if (wasSynchronouslyLoaded) {
          return child;
        }
        return AnimatedOpacity(
          opacity: frame == null ? 0 : 1,
          duration: const Duration(milliseconds: 500),
          curve: Curves.easeIn,
          child: child,
        );
      },
    );
  }

  ///文字渲染后大大小
  static Size boundingTextSize({
    required BuildContext context,
    required String text,
    required TextStyle style,
    int maxLines = 2 ^ 31,
    double maxWidth = double.infinity,
  }) {
    if (text.isEmpty) {
      return Size.zero;
    }
    final textPainter = TextPainter(
        textDirection: TextDirection.ltr,
        locale: Localizations.localeOf(context),
        text: TextSpan(text: text, style: style),
        maxLines: maxLines)
      ..layout(maxWidth: maxWidth);
    return textPainter.size;
  }

// //  图片压缩
// static Future<File> imageCompress({required String path}) async {
//   final file = File(path);
//   CoreKitLogger().d('file.lengthSync ========${file.lengthSync}');
//   if (file.lengthSync() < 200 * 1024) {
//     return file;
//   }
//   var quality = 100;
//   if (file.lengthSync() > 4 * 1024 * 1024) {
//     quality = 50;
//   } else if (file.lengthSync() > 2 * 1024 * 1024) {
//     quality = 60;
//   } else if (file.lengthSync() > 1 * 1024 * 1024) {
//     quality = 70;
//   } else if (file.lengthSync() > 0.5 * 1024 * 1024) {
//     quality = 80;
//   } else if (file.lengthSync() > 0.25 * 1024 * 1024) {
//     quality = 90;
//   }
//
//   final dir = await path_provider.getTemporaryDirectory();
//   final targetPath =
//       '${dir.absolute.path}/${DateTime.now().millisecondsSinceEpoch}.jpg';
//   final result = await FlutterImageCompress.compressAndGetFile(
//     path,
//     targetPath,
//     quality: quality,
//   );
//   return File(result!.path);
// }
//
// //  图片压缩
// static Future<Uint8List?> imageCompressByWeb(
//     {required Uint8List data}) async {
//   // final file = File(path);
//   //
//   // CoreKitLogger().d('file.lengthSync ========${file.lengthSync}');
//   // if (file.lengthSync() < 200 * 1024) {
//   //   return data;
//   // }
//   // var quality = 100;
//   // if (file.lengthSync() > 4 * 1024 * 1024) {
//   //   quality = 50;
//   // } else if (file.lengthSync() > 2 * 1024 * 1024) {
//   //   quality = 60;
//   // } else if (file.lengthSync() > 1 * 1024 * 1024) {
//   //   quality = 70;
//   // } else if (file.lengthSync() > 0.5 * 1024 * 1024) {
//   //   quality = 80;
//   // } else if (file.lengthSync() > 0.25 * 1024 * 1024) {
//   //   quality = 90;
//   // }
//
//   try {
//     final result = await FlutterImageCompress.compressWithList(
//       data,
//       quality: 80,
//     );
//     return result;
//   } catch (error, stackTrace) {
//     // 非标准的BaseResponse，跳过
//     CoreKitLogger()
//         .e('imageCompressByWeb heave some eror', error, stackTrace);
//     return null;
//   }
// }
//
// //  视频压缩
// static Future<File?> videoCompress({required String path}) async {
//   try {
//     await VideoCompress.setLogLevel(0);
//     final info = await VideoCompress.compressVideo(
//       path,
//       quality: VideoQuality.MediumQuality,
//       includeAudio: true,
//     );
//
//     if (info != null) {
//       return File(info.path!);
//     } else {
//       return null;
//     }
//   } catch (error, stackTrace) {
//     CoreKitLogger().e('', error, stackTrace);
//     return null;
//   }
// }
}
